import {useRef, useState} from "react";
import {Input, message} from "antd";
import {useRequest} from "ahooks";
import {speakText} from '@/utils/speak'
import {sleep} from "@/types/jsUtil";

const getCommitBarcode = (TechId: number) => {
  return [
    `CT${TechId}OK`,
    `CT${TechId}NG`,
  ]
}

export const useScanBarcode = <R>({
                                 techId = -1,
                                 enterCallback = (barcode: any): Promise<R> => (Promise.reject({} as R)),
                                 commitCallback = (inCode, inCommitCode, techId): Promise<any> => Promise.reject(`没有提供commit函数`),
                                 startMessage = `提交条码成功`,
                                 errorMessage = `提交条码出错`,
                                 speak = true,
                               }) => {
  const scanInputRef = useRef<Input>(null)
  const [barcode, setBarcode] = useState('');
  const [latestBarcode, setLatestBarcode] = useState('');

  const focusScan = () => void scanInputRef?.current?.focus()

  const [passCode, cancelCode] = getCommitBarcode(techId);

  const _speakText = (s)=> speak && speakText(s)

  const commitReq = useRequest(async (inCommitCode, inCode) =>
       await commitCallback(inCode, inCommitCode, techId)
    , {
      manual: true,
      async onSuccess(data) {
        const msg = `${startMessage} ${data.Message}`
        _speakText(msg)
        await message.success(msg);
      },
      async onError(result) {
        _speakText(`~${errorMessage}! ~`)
      }
    });

  const scanReq = useRequest<R>((barcode) => {
    const msg = `~ 识别条码成功! ~`
    _speakText(msg)
    return message.success(msg)
      .then(sleep)
      .then(() => enterCallback(barcode))
  }, {
    manual: true,
    debounceInterval: 1000,
    async onError(result) {
      _speakText(`~ 扫描条码出错! ${result.message} ~`)
    }
  });

  const onPressEnter = async _ => {
    if (passCode === barcode || cancelCode === barcode) {
      if (!latestBarcode) {
        message.warning(`请先扫描需要操作物品的条码`);
        setBarcode('')
      } else {
        try {
          await commitReq.run(barcode, latestBarcode)
          setLatestBarcode('')
        } catch (e) {
          console.log(e)
        } finally {
          setBarcode('')
        }
      }

    } else {
      try {
        await scanReq.run(barcode)
      } catch (e) {
        console.log(e)
      } finally {
        setLatestBarcode(barcode)
        setBarcode('')
      }
    }
  }

  return {
    scanReq,
    commitReq,
    focusScan,
    scanInputRef,
    commitCodeEnum: {passCode, cancelCode},
    scanBarcodeProps: {
      onPressEnter,
      value: barcode,
      onChange: ({target: {value}}) => {
        setBarcode(value)
      },
      ref: scanInputRef,
    }
  }
}
